﻿#ifndef _EVENT_H_
#define _EVENT_H_ 1
#pragma once

#include <list>
#include "kernel/Referenced.h"

namespace FD
{
	namespace Kernel
	{
		class EventObject;
		/// <summary>
		/// 事件基类
		/// 里面定义了事件类型枚举，可通过事件类型来构造
		/// </summary>
		class FD_Kernel_Export Event : public FD::Kernel::CReferenced
		{
		public:
			/*
			0-1000   为FD::Kernel::Event事件类型
			1001-2000 为guievent_def.h中公共事件类型
			2001-3000 为frameworkevent.h中中间层事件类型
			3001-4000 为spatial3devent.h中事件类型

			*/
			enum Type
			{
				None = 0,                               			/// 无效事件
				Timer = 1,                              			/// 定时器事件
				MouseButtonPress = 2,                   			/// 鼠标按钮按下
				MouseButtonRelease = 3,                 			/// 鼠标按钮释放
				MouseButtonDblClick = 4,                			/// 鼠标按钮双击
				MouseMove = 5,                          			/// 鼠标移动
				KeyPress = 6,                           			/// 键盘键按下
				KeyRelease = 7,                         			/// 键盘键释放
				FocusIn = 8,                            			/// 获得键盘焦点
				FocusOut = 9,                           			/// 失去键盘焦点
				Enter = 10,                             			/// 鼠标进入部件
				Leave = 11,                             			/// 鼠标离开部件
				Paint = 12,                             			/// 绘制部件
				Move = 13,                              			/// 移动部件
				Resize = 14,                            			/// 改变部件大小
				Create = 15,                            			/// 部件已创建
				Destroy = 16,                           			/// 部件正在被销毁
				Show = 17,                              			/// 部件已显示
				Hide = 18,                              			/// 部件已隐藏
				Close = 19,                             			/// 请求关闭部件
				Quit = 20,                              			/// 请求退出程序
				ParentChange = 21,                      			/// 部件父对象被改变
				ParentAboutToChange = 22,               			/// 部件父对象即将被改变
				WindowActivate = 23,                    			/// 窗口成为活动状态
				WindowDeactivate = 24,                  			/// 窗口成为非活动状态
				WindowTitleChange = 25,                 			/// 窗口标题改变
				WindowIconChange = 26,                  			/// 窗口图标改变
				ApplicationWindowIconChange = 27,       			/// 程序图标改变
				ApplicationFontChange = 28,             			/// 程序字体改变
				ApplicationPaletteChange = 29,          			/// 系统调色板改变
				PaletteChange = 30,                     			/// 部件调色板改变
				SocketAct = 31,                         			/// socket激活事件
				DeferredDelete = 32,                    			/// 延迟删除事件
				ChildAdded = 33,                        			/// 增加了子部件
				ChildRemoved = 34,                      			/// 删除了子部件
				LanguageChange = 35,                    			/// 语言改变
				FontChange = 36,                        			/// 字体改变
				EnabledChange = 37,                     			/// 可用状态改变
				ActivationChange = 38,                  			/// 窗口活动状态改变
				StyleChange = 39,                       			/// 风格改变
				IconTextChange = 40,                    			/// 图标文字改变
				MouseTrackingChange = 41,               			/// 鼠标跟踪状态改变
				WindowBlocked = 42,                     			/// 窗口将被阻塞
				WindowUnblocked = 43,                   			/// 窗口从阻塞中恢复
				ToolTip = 44,                           			/// 工具提示事件
				ThreadChange = 45,                      			/// 线程改变事件
				WinEventAct = 46,                       			/// win事件激活
				ZeroTimerEvent = 47,                    			/// 0秒定时器事件
				SockAct = 48,
				UpdateRequest = 49,									/// 请求重绘
				/// Last type used: 49
				User = 50,                                 			///用户事件id
				MaxUser = 50                         			/// 最后的用户事件id
			};
			/// <summary>
			/// 构造函数，通过事件类型构造
			/// </summary>
			/// <param name="type">事件类型</param>
			/// <returns></returns>
			Event(uint16 type);
			Event(uint16 type, FD::Kernel::EventObject *sender);

		public:
			/// <summary>
			/// 析构函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			virtual ~Event() {}
			/// <summary>
			/// 获得事件类型
			/// </summary>
			/// <param name=""></param>
			/// <returns>事件类型</returns>
			uint16 type() const;

			FD::Kernel::EventObject *sender();
			/// <summary>
			/// 判断该事件是否已被post
			/// </summary>
			/// <param name=""></param>
			/// <returns>是返回true，否返回false</returns>
			bool posted() const;
			/// <summary>
			/// 设置该事件是否已被post
			/// </summary>
			/// <param name="posted">是否被post</param>
			/// <returns></returns>
			void setPosted(bool posted);
		protected:
			uint16 m_type;
			bool m_posted;
			FD::Kernel::EventObject *m_pSender;
		};
		/// <summary>
		/// 定时器事件类，从FD::Kernel::Event派生
		/// </summary>
		class FD_Kernel_Export TimerEvent : public FD::Kernel::Event
		{
		public:
			/// <summary>
			/// 代参构造函数，通过定时器id和事件发送目标构造
			/// </summary>
			/// <param name="timerId">定时器id</param>
			/// <param name="dst">接受事件的对象</param>
			/// <returns></returns>
			TimerEvent(int32 timerId, FD::Kernel::EventObject *dst);

		public:
			/// <summary>
			/// 析构函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			virtual ~TimerEvent();
			/// <summary>
			/// 获得定时器事件的定时器id
			/// </summary>
			/// <param name=""></param>
			/// <returns>定时器id</returns>
			int32 timerID() const;
			/// <summary>
			/// 获得定时器事件的接收者对象
			/// </summary>
			/// <param name=""></param>
			/// <returns>接收者对象</returns>
			FD::Kernel::EventObject *receiver() const;
		protected:
			int32 m_iRefCount;
			int32 m_id;
			FD::Kernel::EventObject *m_pObject;
			friend class CSysTimer;
		};
		/// <summary>
		/// 对象模型的基类
		/// 提供定时器、事件处理方法、对象初始化方法
		/// </summary>
		class FD_Kernel_Export EventObject : public FD::Kernel::CReferenced
		{
		public:
			/// <summary>
			/// 构造函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			EventObject();
			/// <summary>
			/// 析构函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			virtual ~EventObject();
			/// <summary>
			/// 启动一个定时器，返回定时器id，时间间隔为interval
			/// </summary>
			/// <param name="interval">定时器时间间隔</param>
			/// <returns>定时器id，大于0的值为有效定时器id</returns>
			int32 startTimer(int32 interval);
			/// <summary>
			/// 注销指定定时器id的定时器
			/// </summary>
			/// <param name="id">定时器id</param>
			/// <returns>成功返回true，否则返回false</returns>
			bool killTimer(int32 id);
			/// <summary>
			/// 事件处理函数，可重载
			/// </summary>
			/// <param name="e">事件</param>
			/// <returns>已处理返回true，否则返回false</returns>
			virtual bool onEvent(FD::Kernel::Event *e);
			/// <summary>
			/// 定时器事件处理函数，可重载
			/// </summary>
			/// <param name="e">定时器事件，内有定时器id</param>
			/// <returns></returns>
			virtual void onTimerEvent(FD::Kernel::TimerEvent *e);
			/// <summary>
			/// 用户自定义事件处理函数，是onEvent的子过程，可重载
			/// </summary>
			/// <param name="e">事件</param>
			/// <returns></returns>
			virtual void onCustomEvent(FD::Kernel::Event *e);
		private:
			/// post事件队列中的事件个数
			int32  m_nPostedEvents;
			friend class EventDispatcher;
		};
		enum EventPriority
		{
			HighEventPriority = 1,
			NormalEventPriority = 0,
			LowEventPriority = -1
		};
		class CPostEvent;
		/// <summary>
		/// 事件分发器类
		/// 用户可通过该类的静态函数向对象发送同步或异步事件
		/// </summary>
		class FD_Kernel_Export EventDispatcher : public FD::Kernel::EventObject
		{
		public:
			/// <summary>
			/// 构造函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			EventDispatcher();
			/// <summary>
			/// 析构函数
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			~EventDispatcher();

		public:
			/// <summary>
			/// 向指定对象发送同步事件
			/// </summary>
			/// <param name="receiver">事件接收者对象</param>
			/// <param name="e">事件</param>
			/// <returns>发送成功返回true，否则返回false</returns>
			static bool sendEvent(FD::Kernel::EventObject *receiver, FD::Kernel::Event *e);
			/// <summary>
			/// 向指定对象发送异步事件，主要用在从工作线程向主线程发送事件
			/// </summary>
			/// <param name="receiver">事件接收者对象</param>
			/// <param name="e">事件</param>
			/// <param name="priority">事件优先级，一般为NormalEventPriority</param>
			/// <returns>发送成功返回true，否则返回false</returns>
			static bool postEvent(FD::Kernel::EventObject *receiver, FD::Kernel::Event *e, int32 priority);

			/// <summary>
			/// 移除异步事件接收者
			/// </summary>
			/// <param name="receiver">事件接收者对象</param>
			/// <returns></returns>
			static void removePostedEvents(FD::Kernel::EventObject *receiver);

			/// <summary>
			/// 移除指定类型的异步事件接收者
			/// </summary>
			/// <param name="receiver">事件接收者对象</param>
			/// <param name="eventType">事件类型</param>
			/// <returns></returns>
			static void removePostedEvents(FD::Kernel::EventObject *receiver, int eventType);
			/// <summary>
			/// 处理并发送事件
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			static void processEvents();
			/// <summary>
			/// 从事件队列中删除已发送的异步定时器事件
			/// </summary>
			/// <param name="object">事件接收者对象</param>
			/// <param name="timerID">定时器id</param>
			/// <returns></returns>
			static void removePostedTimerEvent(FD::Kernel::EventObject *pObject, int32 timerID);
			/// <summary>
			/// 重载的事件处理函数
			/// </summary>
			/// <param name="e">事件</param>
			/// <returns>处理了返回true，没处理返回false</returns>
			virtual bool onEvent(FD::Kernel::Event *e);
		private:
			/// <summary>
			/// 发送所有异步事件
			/// </summary>
			/// <param name=""></param>
			/// <returns></returns>
			static void sendPostedEvents();
			/// <summary>
			/// 注册定时器的内部函数
			/// </summary>
			/// <param name="interval">定时器时间间隔</param>
			/// <param name="object">定时器的开启者</param>
			/// <returns>定时器id</returns>
			static int32 registerTimer(int32 interval, FD::Kernel::EventObject *pObject);
			/// <summary>
			/// 注销定时器的内部函数
			/// </summary>
			/// <param name="id">定时器id</param>
			/// <returns>成功返回true，否则返回false</returns>
			static bool unregisterTimer(int32 id);
		private:
			static std::list<CPostEvent *> ms_listEvents;
			friend class EventObject;
		};
	}
}

#endif
